//
//  MLMenuScene.m
//  WaterProof
//
//  Created by victor0321 on 11/12/23.
//  Copyright __MyCompanyName__ 2011年. All rights reserved.
//


// Import the interfaces
#import "MLMenuScene.h"

#define PTM_RATIO 32

@interface MLMenuScene()
-(CGPoint) locationFromTouches:(NSSet *)touches;    // get the location from touch
-(void) itemPlayTouched:(id)sender;                 // respond to play item touch
-(void) itemOptionTouched:(id)sender;               // respond to option item touch
-(void) itemBackTouched:(id)sender;                 // respond to credit item touch
-(void) stageTouched:(id)sender;                    // respond to stage item touch
-(b2Vec2) toMeters:(CGPoint)point;                  // convert a CGPoint to a b2Vec2
-(CGPoint) toPixels:(b2Vec2)vec;                    // convert a b2Vec2 to a CGPoint
-(void) createBox2DWorld;                           // create the world of box2d
-(void) createBackground;                           // background and title
-(void) createMenu;                                 // create menu
-(void) createStage;                                // create stage
@end

@implementation MLMenuScene

#pragma mark 
#pragma mark === The method added by us ===
#pragma mark

-(b2Vec2) toMeters:(CGPoint)point{
	return b2Vec2(point.x / PTM_RATIO, point.y / PTM_RATIO);
}

-(CGPoint) toPixels:(b2Vec2)vec{
	return ccpMult(CGPointMake(vec.x, vec.y), PTM_RATIO);
}

-(CGPoint) locationFromTouches:(NSSet *)touches{
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInView:[touch view]];
    return [[CCDirector sharedDirector] convertToGL:touchLocation];
}

#pragma mark
#pragma mark === Scene initialization ===
#pragma mark

+(CCScene *) scene{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];
	
	// 'layer' is an autorelease object.
	MLMenuScene *layer = [MLMenuScene node];
	
	// add layer as a child to scene
	[scene addChild: layer];
	
	// return the scene
	return scene;
}

-(void) createBox2DWorld{
    
    // Construct a world object, which will hold and simulate the rigid bodies.
    b2Vec2 gravity = b2Vec2(0.0f, 0.0f);
    bool allowBodiesToSleep = false;
    world = new b2World(gravity, allowBodiesToSleep);
    
    // Define the static container body, which will provide the collisions at screen borders.
    b2BodyDef containerMenuDef;
    b2BodyDef containerStageDef;
    b2Body* containerMenu = world->CreateBody(&containerMenuDef);

    
    // for the ground body we'll need these values
    
    float widthInMeters = screenSize.width / PTM_RATIO;
    float heightInMeters = ((screenSize.height+120)/2) / PTM_RATIO;
    b2Vec2 lowerLeftCorner = b2Vec2(0, -(149/PTM_RATIO));
    b2Vec2 lowerRightCorner = b2Vec2(widthInMeters, -(149/PTM_RATIO));
    b2Vec2 upperLeftCorner = b2Vec2(0, heightInMeters);
    b2Vec2 upperRightCorner = b2Vec2(widthInMeters, heightInMeters);
    
    // Create the screen box' sides by using a polygon assigning each side individually.
    b2PolygonShape screenBoxShape;
    int density = 0;
    
    // bottom
    screenBoxShape.SetAsEdge(lowerLeftCorner, lowerRightCorner);
    containerMenu->CreateFixture(&screenBoxShape, density);
    
    // top
    screenBoxShape.SetAsEdge(upperLeftCorner, upperRightCorner);
    containerMenu->CreateFixture(&screenBoxShape, density);
    
    // left side
    screenBoxShape.SetAsEdge(upperLeftCorner, lowerLeftCorner);
    containerMenu->CreateFixture(&screenBoxShape, density);
    
    // right side
    screenBoxShape.SetAsEdge(upperRightCorner, lowerRightCorner);
    containerMenu->CreateFixture(&screenBoxShape, density);
    
}

-(void) createBackground{
    
    // background
    CCSprite* menuBackGround = [CCSprite spriteWithFile:@"MenuBackground.png"];
    menuBackGround.position = CGPointMake(screenSize.width / 2, screenSize.height / 2);
    [self addChild:menuBackGround];
    
    /*CCSprite* menuWater = [CCSprite spriteWithFile:@"MenuWater.png"];
    menuWater.anchorPoint = ccp(0.5,0);
    menuWater.position = CGPointMake(screenSize.width/2, 0);
    [self addChild:menuWater];*/
        
    // title
    CCSprite* title = [CCSprite spriteWithFile:@"title.png"];
    title.anchorPoint = CGPointMake(0.5, 1);
    title.position =  ccp( screenSize.width /2 , screenSize.height);
    
    /*CCMoveBy* move1 = [CCMoveBy actionWithDuration:1 position:CGPointMake(0, -10)];
    CCMoveBy* move2 = [CCMoveBy actionWithDuration:1 position:CGPointMake(0, 10)];
    CCSequence* sequence = [CCSequence actions:move1, move2, nil];
    CCRepeatForever* repeat = [CCRepeatForever actionWithAction:sequence];
    [title runAction:repeat];*/

    [self addChild: title];
    
    // water surface
    MLWaterSurface* surface1 = [MLWaterSurface waterSurface:1];
    surface1.position = CGPointMake(screenSize.width/2, screenSize.height/2 - 50);
    [self addChild:surface1];
    
    /*MLWaterSurface* surface2 = [MLWaterSurface waterSurface:2];
    surface2.position = CGPointMake(screenSize.width/2, screenSize.height/2 - 50);
    [self addChild:surface2];*/
}

-(void) createMenu{
    
    MLMenuObject* menuPlayObject = [[MLMenuObject alloc] init];
    MLMenuObject* menuOptionObject = [[MLMenuObject alloc] init];
    MLMenuObject* menuBackObject = [[MLMenuObject alloc] init];
    
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    b2PolygonShape dynamicBox;
    b2FixtureDef fixtureDef;
    
    fixtureDef.density = 0.3f;
    fixtureDef.friction = 0.5f;
    fixtureDef.restitution = 0.2f;
    
    // play
    play = [CCSprite spriteWithFile:@"btn_play.png"];
    CCSprite* playSelected = [CCSprite spriteWithFile:@"btn_play.png"];
    playSelected.color = ccGRAY;
    CCMenuItemSprite* itemPlay = [CCMenuItemSprite itemFromNormalSprite:play selectedSprite:playSelected target:self selector:@selector(itemPlayTouched:)];
    itemPlay.position = ccp( screenSize.width /2+100 , screenSize.height/2);
    
    [menuPlayObject setMenuItem:itemPlay];
    [menuPlayObject setIsMenu:YES];
    [menuPlayObject setLock:NO];
    [menuPlayObject setState:floating];
    bodyDef.position = [self toMeters:itemPlay.position];
    bodyDef.userData = menuPlayObject;
    b2Body* bodyPlay = world->CreateBody(&bodyDef);
    
    dynamicBox.SetAsBox((play.contentSize.width/PTM_RATIO)*0.5, (play.contentSize.height/PTM_RATIO)*0.5);
    fixtureDef.shape = &dynamicBox;
    bodyPlay->CreateFixture(&fixtureDef);

    // option
    option = [CCSprite spriteWithFile:@"btn_option.png"];
    CCSprite* optionSelected = [CCSprite spriteWithFile:@"btn_option.png"];
    optionSelected.color = ccGRAY;
    CCMenuItemSprite* itemOption = [CCMenuItemSprite itemFromNormalSprite:option selectedSprite:optionSelected target:self selector:@selector(itemOptionTouched:)];
    itemOption.position = ccp( screenSize.width /2-100 , screenSize.height/2);
    
    [menuOptionObject setMenuItem:itemOption];
    [menuOptionObject setIsMenu:YES];
    [menuOptionObject setLock:NO];
    [menuOptionObject setState:floating];
    bodyDef.position = [self toMeters:[itemOption position]];
    bodyDef.userData = menuOptionObject;
    b2Body* bodyOption = world->CreateBody(&bodyDef);
    
    dynamicBox.SetAsBox((option.contentSize.width/PTM_RATIO)*0.5, (option.contentSize.height/PTM_RATIO)*0.5);
    fixtureDef.shape = &dynamicBox;
    bodyOption->CreateFixture(&fixtureDef);
    
    // back
    back = [CCSprite spriteWithFile:@"btn_back.png"];
    back.color = ccYELLOW;
    CCSprite* backSelected = [CCSprite spriteWithFile:@"btn_back.png"];
    backSelected.color = ccGREEN;
    CCMenuItemSprite* itemBack = [CCMenuItemSprite itemFromNormalSprite:back selectedSprite:backSelected target:self selector:@selector(itemBackTouched:)];
    itemBack.position = ccp( screenSize.width - back.contentSize.width/2 , -play.contentSize.height/2);
    
    [menuBackObject setMenuItem:itemBack];
    [menuBackObject setIsMenu:NO];
    [menuBackObject setLock:NO];
    [menuBackObject setState:ground];
    bodyDef.position = [self toMeters:[itemBack position]];
    bodyDef.userData = menuBackObject;
    b2Body* bodyBack = world->CreateBody(&bodyDef);
    
    dynamicBox.SetAsBox((back.contentSize.width/PTM_RATIO)*0.5, (back.contentSize.height/PTM_RATIO)*0.5);
    fixtureDef.shape = &dynamicBox;
    bodyBack->CreateFixture(&fixtureDef);
    
    // create menu
    CCMenu* menu = [CCMenu menuWithItems:itemPlay, itemOption, itemBack, nil];
    [self addChild:menu];
    menu.position = CGPointZero;
}

-(void) createStage{
    
    CCMenu* stageMenu = [CCMenu menuWithItems: nil];
    
    for(int i = 1; i <= 5 ;i++)
    {
        MLMenuObject* stageObject = [[MLMenuObject alloc] init];
        
        b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        
        NSString* file = [NSString stringWithFormat:@"stage%i.png", i];
        CCSprite* stage = [CCSprite spriteWithFile:file];
        CCSprite* stageSelected = [CCSprite spriteWithFile:file];
        stageSelected.color = ccGRAY;
        CCMenuItemSprite* itemStage = [CCMenuItemSprite itemFromNormalSprite:stage selectedSprite:stageSelected target:self selector:@selector(stageTouched:)];
        
        [stageObject setMenuItem:itemStage];
        [stageObject setIsMenu:NO];
        if(i == 1)
            [stageObject setLock:NO];
        else
            [stageObject setLock:YES];
        [stageObject setState:ground];
        
        itemStage.tag = i;
        itemStage.userData = stageObject;
        itemStage.position = ccp(CCRANDOM_0_1()*(1024-back.contentSize.width), -stage.contentSize.height/2);
        
        bodyDef.position = [self toMeters:itemStage.position];
        bodyDef.userData = stageObject;
        b2Body* bodyStage = world->CreateBody(&bodyDef);
        
        b2PolygonShape dynamicBox;
        dynamicBox.SetAsBox((stage.contentSize.width/PTM_RATIO)*0.5,(stage.contentSize.height/PTM_RATIO)*0.5);
        
        b2FixtureDef fixtureDef;
        fixtureDef.shape = &dynamicBox;
        fixtureDef.density = 0.3f;
        fixtureDef.friction = 0.5f;
        fixtureDef.restitution = 0.2f;
        bodyStage->CreateFixture(&fixtureDef);
        
        [stageMenu addChild:itemStage];
    }
    stageMenu.position = CGPointZero;
    [self addChild:stageMenu];
}

// on "init" you need to initialize your instance
-(id) init
{
    if( (self = [super init]) ){
        
        CCLOG(@"===========================================");
        CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
        self.isTouchEnabled = YES;
        self.isAccelerometerEnabled = YES;
        screenSize = [CCDirector sharedDirector].winSize;
        
        srandom(time(NULL));
        [self createBox2DWorld];
        [self createBackground];
        [self createMenu];
        [self createStage];
        
        [self scheduleUpdateWithPriority:-1];
        
        // Water effect
        //[self runWaterEffect];
        
        //id waves = [CCWaves actionWithWaves:5*30 amplitude:5 horizontal:YES vertical:NO grid:ccg(15, 10) duration:10*30];
        
        //background music
        [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"mainBackGround.mp3" loop:YES];

        
        
    }
	return self;
}

-(void) update:(ccTime)delta
{
    float timeStep = 0.03f;
    int32 velocityIterations = 8;
    int32 positionIterations = 1;
    world->Step(timeStep, velocityIterations, positionIterations);
    
    for (b2Body* body = world->GetBodyList(); body != nil; body = body->GetNext())
    {
        MLMenuObject* sprite = (MLMenuObject*)body->GetUserData();
        //[[sprite menuItem] contentSize].height;
        if(sprite !=NULL)
        {
            //if(![sprite menu])
            //    NSLog(@"%i", [sprite state]);
            switch ([sprite state]) {
                case floating:{
                    body->ApplyForce(b2Vec2(0.0, 3*body->GetMass()), body->GetPosition());
                    float angle = body->GetAngle();
                    [sprite menuItem].rotation = CC_RADIANS_TO_DEGREES(angle) * -1;
                    if([[sprite menuItem] numberOfRunningActions] == 0)
                    {
                        CCMoveBy* move1 = [CCMoveBy actionWithDuration:1 position:CGPointMake(0, -10)];
                        CCMoveBy* move2 = [CCMoveBy actionWithDuration:1 position:CGPointMake(0, 10)];
                        CCSequence* sequence = [CCSequence actions:move1, move2, nil];
                        CCRepeatForever* repeat = [CCRepeatForever actionWithAction:sequence];
                        [[sprite menuItem] runAction:repeat]; 
                    }
                    break;
                }
                case falling:{
                    [[sprite menuItem] stopAllActions];
                    body->ApplyForce(b2Vec2(0.0, -3*body->GetMass()), body->GetPosition());
                    [sprite menuItem].position = [self toPixels:body->GetPosition()];
                    float angle = body->GetAngle();
                    [sprite menuItem].rotation = CC_RADIANS_TO_DEGREES(angle) * -1;
                    if([sprite menuItem].position.y <= -(play.contentSize.height/2))
                        [sprite setState:ground];
                    break;
                }
                case ground:{
                    [[sprite menuItem] stopAllActions];
                    body->ApplyForce(b2Vec2(0.0, -3*body->GetMass()), body->GetPosition());
                    [sprite menuItem].position = [self toPixels:body->GetPosition()];
                    float angle = body->GetAngle();
                    [sprite menuItem].rotation = CC_RADIANS_TO_DEGREES(angle) * -1;
                    break;
                }
                case rising:{
                    [[sprite menuItem] stopAllActions];
                    body->ApplyForce(b2Vec2(0.0, 3*body->GetMass()), body->GetPosition());
                    [sprite menuItem].position = [self toPixels:body->GetPosition()];
                    float angle = body->GetAngle();
                    [sprite menuItem].rotation = CC_RADIANS_TO_DEGREES(angle) * -1;
                    if([sprite menuItem].position.y >= (screenSize.height)/2)
                        [sprite setState:floating];
                    break;
                }
                default:
                    break;
            }
        }
    }
}

#pragma mark
#pragma mark === Touch handling ===
#pragma mark

-(void) itemPlayTouched:(id)sender {
    
    if (menu_stage == MENU) {
        menu_stage = STAGE;
        for (b2Body* body = world->GetBodyList(); body != nil; body = body->GetNext())
        {
            MLMenuObject* sprite = (MLMenuObject*)body->GetUserData();
            if(sprite !=NULL)
            {
                if([sprite isMenu])
                    [sprite setState:falling];
                else
                    [sprite setState:rising];
            }
        }
    }
    [[SimpleAudioEngine sharedEngine] playEffect:@"puton.caf"]; 
}

-(void) itemOptionTouched:(id)sender {
    [[SimpleAudioEngine sharedEngine] playEffect:@"puton.caf"];  

}

-(void) itemBackTouched:(id)sender {
    
    if (menu_stage == STAGE) {
        menu_stage = MENU;
        for (b2Body* body = world->GetBodyList(); body != nil; body = body->GetNext())
        {
            MLMenuObject* sprite = (MLMenuObject*)body->GetUserData();
            if(sprite !=NULL)
            {
                if([sprite isMenu])
                    [sprite setState:rising];
                else
                    [sprite setState:falling];
            }
        }
    }
    [[SimpleAudioEngine sharedEngine] playEffect:@"drop2.caf"]; 

}

-(void) stageTouched:(id)sender{
    
    if (menu_stage == MENU) {
        return;
    }
    NSAssert([sender isKindOfClass:[CCMenuItemSprite class]], @"node is not a CCMenuItem!");
    
    MLMenuObject* touchStage = (MLMenuObject*)[sender userData];
    NSInteger stageNum = [sender tag];

    if([touchStage lock])
    {
        return;
        NSLog(@"lock");
        NSLog(@"%i", stageNum);
    }
    else
    {
        if(stageNum == 1)
            [[CCDirector sharedDirector] replaceScene:[MLLoadingScene sceneWithStage:Stage1]];
        else if(stageNum == 2)
            [[CCDirector sharedDirector] replaceScene:[MLLoadingScene sceneWithStage:Stage2]];
    }
    [[SimpleAudioEngine sharedEngine] playEffect:@"drop2.caf"];
    
}

-(void) ccTouchesBegin:(NSSet *)touches withEvent:(UIEvent *)event{
    

}

-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    
}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event{
  
}

#pragma mark
#pragma mark === Release method ===
#pragma mark

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
	CCLOG(@"===========================================");
    CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
    delete world;
	// don't forget to call "super dealloc"
	[super dealloc];
}
@end
